import traceback
from flask import Blueprint, current_app, request, jsonify
from flask_caching import Cache
import akshare as ak
import math
import pandas as pd
from app.models import db, User, Transaction, UserAsset, AssetTypeEnum, Preference, UserBehaviorStats
from datetime import datetime

forex_controller = Blueprint('forex_controller', __name__)
cache = Cache(config={'CACHE_TYPE':'simple'})

@forex_controller.before_app_request
def init_cache():
    cache.init_app(current_app)

@forex_controller.before_request
def log_request():
    current_app.logger.info(f"[FOREX] {request.method} {request.url}")

@forex_controller.get('/spot_list')
def get_info():
    """
    GET /forex/spot_list
    获取实时外汇行情列表,字段包括：
    序号    int64	-
    代码    object	-
    名称    object	-
    最新价    float64	-
    涨跌额   float64	-
    涨跌幅    float64	-
    今开   float64	-
    最高   float64	-
    最低   float64	-
    昨收   float64	-
    """
    cache_key = 'forex:spot_list'
    data = cache.get(cache_key)
    if data :
        # current_app.logger.debug(f"[FOREX] 从缓存中获取外汇行情信息")
        return jsonify({'code': 0, 'data': data})
    try:
        df=ak.forex_spot_em()
        df=df.rename(columns={
            '序号': 'index',
            '代码': 'code',
            '名称': 'name',
            '最新价': 'latest_price',
            '涨跌额': 'change_amount',
            '涨跌幅': 'change_rate',
            '今开': 'open',
            '最高': 'high',
            '最低': 'low',
            '昨收': 'previous_close'
        })
        df = df.where(pd.notnull(df), None)
        # current_app.logger.debug(f"[FOREX] raw columns = {df.columns.tolist()}")
        # current_app.logger.debug(f"[FOREX] raw data = {df.head().to_dict(orient='records')}")
        # 将DataFrame转换为字典列表
        data = df.to_dict(orient='records')
        cache.set(cache_key, data, timeout=300)

        return jsonify({'code': 0, 'data': data})
    except Exception as e:
        current_app.logger.error(f"[FOREX] 获取外汇行情信息失败: {e}")
        current_app.logger.error(traceback.format_exc())
        return jsonify({'code': 1,'msg': '获取外汇行情信息失败'})
    
@forex_controller.get('/trend')
def get_trend():
    """
    GET /forex/trend
    获取外汇价格走势图
    请求参数：
    - code: 外汇代码
    返回字段：
      日期,
      代码,
      名称,
      今开,
      最新价,
      最高,      
      最低,    
      振幅
    """
    symbol = request.args.get('symbol')
    if not symbol:
        return jsonify({'code': 1,'msg': '缺少 symbol 参数'}), 400
    
    cache_key = f'forex:trend:{symbol}'
    data=cache.get(cache_key)
    if data:
        current_app.logger.debug(f"[FOREX] 从缓存中获取 {symbol} 外汇价格走势图")
        return jsonify({'code': 0, 'data': data})
    try:
        df = ak.forex_hist_em(symbol=symbol)
        df = df.rename(columns={
            '日期': 'date',
            '代码':'symbol',
            '名称': 'name',
            '今开': 'open',
            '最新价': 'close',
            '最高': 'high',
            '最低': 'low',
            '振幅': 'amplitude'
        })
        df = df.where(pd.notnull(df), None)
        records = df.to_dict(orient='records')
        cache.set(cache_key, records, timeout=300)
        return jsonify({'code': 0, 'data': records})
    except Exception as e:
        current_app.logger.error(f"[FOREX] 获取 {symbol} 外汇价格走势图失败: {e}")
        current_app.logger.error(traceback.format_exc())

@forex_controller.post('/buy')
def buy_forex():
    """
    POST /api/stock/buy
    购买股票
    请求参数：
    - userid: 用户ID
    - products_id: 股票代码
    - products_name: 股票名称
    - quantity: 购买数量
    - price: 当前价格
    -trade_time: 交易时间
    """
    try:
        data = request.json
        current_app.logger.debug(f"Request JSON: {data}")  # 打印请求的 JSON 数据
        userid = data.get('userid')
        if isinstance(userid, str):
            userid = int(userid)  # 如果 userid 是字符串，转换为整数

        products_id = data.get('products_id')
        products_name = data.get('products_name')
        quantity = data.get('quantity')
        price = data.get('price')

         

        if not all([userid, products_id, products_name, quantity, price]):
            return jsonify({'code': 1, 'msg': '缺少必要参数'}), 400

        # 设置交易时间为当前时间
        trade_time = datetime.now()
        # 计算交易金额
        trade_amount = quantity * price

        # 更新用户资产
        asset = UserAsset.query.filter_by(userid=userid, products_id=products_id).first()
        if asset:
            asset.quantity += quantity
        else:
            asset = UserAsset(
                userid=userid,
                products_id=products_id,
                products_name=products_name,
                type='外汇',
                quantity=quantity,
                buy_price=price
            )
            db.session.add(asset)

        # 添加交易记录
        transaction = Transaction(
            userid=userid,
            products_id=products_id,
            products_name=products_name,
            type='外汇',
            trade_type='买入',
            quantity=quantity,
            trade_time=trade_time,  # 使用当前时间
            trade_amount=trade_amount
        )
        db.session.add(transaction)
        ##
        behavior_stats = UserBehaviorStats.query.filter_by(user_id=userid).first()
        behavior_stats.total_transactions = UserBehaviorStats.total_transactions + 1
        behavior_stats.total_commission = UserBehaviorStats.total_commission + trade_amount
        ##

        db.session.commit()
        return jsonify({'code': 0, 'msg': '购买成功'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 1, 'msg': f'购买失败: {str(e)}'}), 500
    

@forex_controller.post('/sell')
def sell_forex():
    """
    POST /api/stock/sell
    卖出股票
    请求参数：
    - userid: 用户ID
    - products_id: 股票代码
    - products_name: 股票名称
    - quantity: 卖出数量
    - price: 当前价格
    """
    try:
        data = request.json
        userid = data.get('userid')
        products_id = data.get('products_id')
        products_name = data.get('products_name')
        quantity = data.get('quantity')
        price = data.get('price')

        if not all([userid, products_id, products_name, quantity, price]):
            return jsonify({'code': 1, 'msg': '缺少必要参数'}), 400

        trade_time = datetime.now()  # 设置交易时间为当前时间
        # 检查用户资产是否足够
        asset = UserAsset.query.filter_by(userid=userid, products_id=products_id).first()
        if not asset or asset.quantity < quantity:
            return jsonify({'code': 1, 'msg': '持仓不足，无法卖出'}), 400

        # 计算交易金额
        trade_amount = quantity * price

        # 更新用户资产
        asset.quantity -= quantity
        if asset.quantity == 0:
            db.session.delete(asset)

        # 添加交易记录
        transaction = Transaction(
            userid=userid,
            products_id=products_id,
            products_name=products_name,
            type='外汇',
            trade_type='售出',
            quantity=quantity,
            trade_amount=trade_amount,
            trade_time=trade_time
        )
        db.session.add(transaction)
        ##
        behavior_stats = UserBehaviorStats.query.filter_by(user_id=userid).first()
        behavior_stats.total_transactions = UserBehaviorStats.total_transactions + 1
        behavior_stats.total_commission = UserBehaviorStats.total_commission + trade_amount
        ##
        db.session.commit()
        return jsonify({'code': 0, 'msg': '卖出成功'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 1, 'msg': f'卖出失败: {str(e)}'}), 500

